public abstract class Worker implements Runnable {

	protected Storage putStorage;
	private Storage getStorage;
	private int workTime;
	protected Thread thread;
	private int count;

	protected Worker(Storage getStorage, Storage putStorage, int workTime) {
		this.putStorage = putStorage;
		this.getStorage = getStorage;
		this.putStorage.assignPutter();
		this.count=0;
		this.workTime = workTime;
		this.thread = new Thread(this);
	}

	public boolean get() {
		if (this.getStorage.checkPuttersDone() && this.getStorage.isEmpty()) {
			this.putStorage.removePutter();
			this.stop();
			return true;
		}
		return getStorage.get();
	}

	public boolean put() {
		boolean temp = putStorage.put();
		if(temp) {
			this.count++;
		}
		return temp;
	}

	@Override
	public void run() {
		while (thread != null) {
			while (thread != null && !this.get()) {
				try {
					thread.sleep(1);
				} catch (InterruptedException ex) {
					this.stop();
					break;
				}
			}
			try {
				thread.sleep(workTime);
			} catch (InterruptedException ex) {
				if (this.getStorage != null) {
					this.getStorage.put();
				}
				this.stop();
			}
			while (thread != null && !this.put()) {
				try {
					thread.sleep(1);
				} catch (InterruptedException ex) {
					if (this.getStorage != null) {
						this.getStorage.put();
					}
					this.stop();
				}
			}
		}
	}

	public void stop() {
		if (thread != null) {
			thread = null;
		}
	}
	
	public void start(){
		if (thread != null) {
			this.thread.start();
		}
	}
	
	public void interrupt() {
		if (thread != null) {
			this.thread.interrupt();
			if (thread != null) {
				this.stop();
			}
		}
	}
	
	public String toString() {
		return this.getClass()+":"+this.count*this.putStorage.putCount+"| WorkTime: "+this.workTime;
	}

}
